/*-+-*****************************************************************************
 Copyright (C) 2009-2012 Oceanside Software Corporation (R)
 Dallas, Texas

 Author       : Jason T. Brower
 Purpose      : This file is part of a point-of-sale software package
                originally written for Table-Service Restaurants.
              
 Date         : July 8th of 2012
              
 History      : The application that this software file belongs to was 
                written over a 3-Year period.  The first version was written
                in C# .Net 3.5 using Windows Forms.  Being new to .Net at
                the time, I soon learned of Windows Presentation Foundation,
                liked the graphics capabilities and databinding so I
                migrated to WPF.  When the .Net 4.0 framework was released
                the application was migrated from 3.5 to 4.0. Now today,
                .Net 4.5 RC is out and I was already in process of migrating
                before I made this public.
                
Excuse Me     : Please excuse the coding style, it is not representative of
                my typical work.  During the three years I was under a very
                tight budget, constantly running out of funding and was 
                working 18 hour days hyped up on 5-Hour Energy.  The 
                design is not textbook.  It is monolythic because of
                previous issues I will not get into.  There are few comments
                in the code and the ones that are there may be incorrect.
                
What it is not: This is not the exact version that I took through PA-DSS 2.0
                nor is it the exact version running at my customer sites.
                I removed some details for security purposes including some
                encryption algorithms.  The reporting was removed because
                I was including a third party library that cannot be 
                published with this Open Source.
                
What it is    : This application has been running at high volume restaraunts
                for over a year.  It never freezes, crashes or does anything
                unexpected.  So long as it is built, installed and configured
                correctly, it is a strong system that we can all enhance.

Contact       : Please note that I can no longer work for free.  However, you
                can reach me at information@oceansidesw.com.                                                      

*********************************************************************************/
using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

#if _LOCALDB
  using Oceanside.LocalDB;
#else
using Oceanside.RemoteDB;
#endif
namespace Oceanside
{
    public class PageImpBaseClass
    {

        static Button editFormButton;
        public static Button EditFormButton
        {
            get { return PageImpBaseClass.editFormButton; }
            set { PageImpBaseClass.editFormButton = value; }
        }

        static Button cancelEditButton;
        public static Button CancelEditButton
        {
            get { return PageImpBaseClass.cancelEditButton; }
            set { PageImpBaseClass.cancelEditButton = value; }
        }

        static Button saveFormChangesButton;
        public static Button SaveFormChangesButton
        {
            get { return PageImpBaseClass.saveFormChangesButton; }
            set { PageImpBaseClass.saveFormChangesButton = value; }
        }

        static Button newGroupButton;
        public static Button NewGroupButton
        {
            get { return PageImpBaseClass.newGroupButton; }
            set { PageImpBaseClass.newGroupButton = value; }
        }

        static Button deleteGroupButton;
        public static Button DeleteGroupButton
        {
            get { return PageImpBaseClass.deleteGroupButton; }
            set { PageImpBaseClass.deleteGroupButton = value; }
        }

        static Button newEntityButton;
        public static Button NewEntityButton
        {
            get { return PageImpBaseClass.newEntityButton; }
            set { PageImpBaseClass.newEntityButton = value; }
        }

        static Button deleteEntityButton;
        public static Button DeleteEntityButton
        {
            get { return PageImpBaseClass.deleteEntityButton; }
            set { PageImpBaseClass.deleteEntityButton = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public PageImpBaseClass()
        {
            mTextBoxesList = new List<DbLinkedTextBox>();
            mListofComboboxes = new List<ComboBox>();
            mListOfListOfObects = new List<ListView>();
            mListOfControlsToHideInNonEditMode = new List<UIElement>();
            mListOfControlsToDisableInNonEditMode = new List<UIElement>();
            mListOfControlsToDisableInAllModes = new List<UIElement>();
        }

        protected List<DbLinkedTextBox> mTextBoxesList;

        /// <summary>
        /// 
        /// </summary>
        protected bool mEntityAddDeleteLoggingEnabled = false;

        private static Action hideKeyboard;
        public static Action HideKeyboard
        {
            get { return hideKeyboard; }
            set { hideKeyboard = value; }
        }


        /// <summary>
        /// 
        /// </summary>
        private Action onKeyboardShow = null;
        public Action OnKeyboardShow
        {
            get { return onKeyboardShow; }
            set { onKeyboardShow = value; }
        }

        private static Action showKeyboard;
        public static Action ShowKeyboard
        {
            get { return showKeyboard; }
            set { showKeyboard = value; }
        }

        protected List<UIElement> mListOfControlsToHideInNonEditMode;
        protected List<UIElement> mListOfControlsToDisableInNonEditMode;
        protected List<UIElement> mListOfControlsToDisableInAllModes;

        /// <summary>
        /// 
        /// </summary>
        private bool isProcessingTransaction = false;
        public bool IsProcessingTransaction
        {
            get { return isProcessingTransaction; }
            set { isProcessingTransaction = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        private Brush buttonBackground = _standardButtonBrush;
        public Brush ButtonBackground
        {
            get { return buttonBackground; }
            set { buttonBackground = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        protected bool mCancelIsDisabled = false;
        protected bool mNewEntityIsDisabled = false;
        protected bool mNewGroupIsDisabled = false;
        protected bool mDeleteEntityIsDisabled = false;
        protected bool mDeleteGroupIsDisabled = false;
        protected bool mEditIsDisabled = false;
        protected bool mSaveIsDisabled = false;

        protected string mButtonDeleteEntityName = "";
        protected string mButtonNewEntityName = "";
        protected string mButtonDeleteGroupName = "";
        protected string mButtonNewGroupName = "";

        /// <summary>
        /// 
        /// </summary>
        private static SolidColorBrush _standardButtonBrush;

        /// <summary>
        /// 
        /// </summary>
        static PageImpBaseClass()
        {
            _standardButtonBrush = new SolidColorBrush(Color.FromArgb(0xFF, 0xD6, 0xE5, 0xF5));
        }

        /// <summary>
        /// Used by some pages to indicate a secondary feature or function such as jumping the cursor
        /// to a specific form entry or enabling edit mode.
        /// </summary>
        private Boolean isSpecialMode = false;
        public Boolean IsSpecialMode
        {
            get { return isSpecialMode; }
            set { isSpecialMode = value; }
        }

        public static DominicaEntities Context
        {
            get { return SHIFT.GlobalContext; }
        }

        private string buttonNumber = "";
        public string ButtonNumber
        {
            get { return buttonNumber; }
            set { buttonNumber = value; }
        }

        private string buttonLabelText = "";
        public string ButtonLabelText
        {
            get { return buttonLabelText; }
            set { buttonLabelText = value; }
        }

        private List<ComboBox> mListofComboboxes;
        public List<ComboBox> ListofComboboxes
        {
            get { return mListofComboboxes; }
            set { mListofComboboxes = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        virtual public void ResetFocus()
        {
            UpdateControlsState(FORM_MODES_ENUM.LOCKED, GetSelectedEntityObject(), GetSelectedGroupObject());
            NewGroupButton.Content = mButtonNewGroupName;
            NewEntityButton.Content = mButtonNewEntityName;
            DeleteGroupButton.Content = mButtonDeleteGroupName;
            DeleteEntityButton.Content = mButtonDeleteEntityName;
        }

        /// <summary>
        /// 
        /// </summary>
        virtual public void Navigating()
        {
            UpdateControlsState(FORM_MODES_ENUM.LOCKED, GetSelectedEntityObject(), GetSelectedGroupObject());

            foreach (ComboBox cb in mListofComboboxes)
            {
                cb.ItemsSource = null;
                cb.SelectedItem = null;
            }

            foreach (ListView lv in mListOfListOfObects)
            {
                if (lv != null)
                {
                    lv.ItemsSource = null;
                }
            }
            IsFetched = false;
        }

        /// <summary>
        /// 
        /// </summary>
        virtual public void MarkEntityDeleted()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        virtual public void MarkGroupDeleted()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        virtual public void EditStarted()
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        virtual public EntityObject AddNewEntityObject()
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        virtual public EntityObject AddNewGroupObject()
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        virtual public EntityObject GetSelectedEntityObject()
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        virtual public EntityObject GetSelectedGroupObject()
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        virtual public ComboBox GetEntityComboBox()
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        virtual public ComboBox GetGroupComboBox()
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        virtual public void UpdateUsersEntitySource()
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        virtual public void UpdateUsersGroupSource()
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        virtual public List<EntityObject> GetEntityObjectSet()
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        virtual public List<EntityObject> GetGroupObjectSet()
        {
            return null;
        }

        /// <summary>
        /// 
        /// </summary>
        virtual public void CancelNewEntityWasClicked()
        {

        }

        /// <summary>
        /// 
        /// </summary>
        virtual public void CancelNewGroupWasClicked()
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public virtual bool VerifyFormEntries()
        {
            ComboBox groupsComboBox = GetGroupComboBox();
            if (groupsGroupBox != null && groupsComboBox != null && groupsComboBox.SelectedItem != null)
            {
                if (!RecursiveCheckMandatoryFields(groupsGroupBox))
                {
                    return false;
                }
            }

            ComboBox entitiesComboBox = GetEntityComboBox();
            if (entitiesGroupBox != null && entitiesComboBox != null && entitiesComboBox.SelectedItem != null)
            {
                if (!RecursiveCheckMandatoryFields(entitiesGroupBox))
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        public virtual bool SaveMe()
        {
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        protected UIElementCollection uiElementsList;
        public void RegisterUiElementsList(UIElementCollection list)
        {
            uiElementsList = list;
        }

        /// <summary>
        /// 
        /// </summary>
        private List<ListView> mListOfListOfObects;
        public void RegisterListview(ListView lv)
        {
            mListOfListOfObects.Add(lv);
        }

        private GroupBox groupsGroupBox;
        private GroupBox entitiesGroupBox;
        public void RegisterSaveMeGroupBoxes(GroupBox groups, GroupBox entities)
        {
            this.groupsGroupBox = groups;
            this.entitiesGroupBox = entities;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        private static bool StateWasModify(FORM_MODES_ENUM state)
        {
            return (
                state == FORM_MODES_ENUM.DELETE_ENTITY ||
                state == FORM_MODES_ENUM.EDIT_FORM ||
                state == FORM_MODES_ENUM.NEW_ENTITY ||
                state == FORM_MODES_ENUM.DELETE_GROUP ||
                state == FORM_MODES_ENUM.NEW_GROUP);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="state"></param>
        /// <param name="updatedEntity"></param>
        /// <param name="updatedGroup"></param>
        public void UpdateControlsState(FORM_MODES_ENUM state, EntityObject updatedEntity, EntityObject updatedGroup)
        {
            PreviousFormState = currentFormState;
            CurrentFormState = state;

            ///All of the logging for controls is taken care of down in each custom DbLinkedBound control with the 
            ///exception of when a new control is created or deleted.  In those cases when log the creation or
            ///deletion of the object right here and the custom controls will not log the changes because the 
            ///previous form state was not in the new or delete mode.
            if ((state == FORM_MODES_ENUM.LOCKED || state == FORM_MODES_ENUM.SAVE_THEN_EDIT) &&
                StateWasModify(PreviousFormState) && (updatedEntity != null || updatedGroup != null))
            {
                ///The previous state was new, that means we need to update the log with the added verbage.
                if (PreviousFormState == FORM_MODES_ENUM.NEW_ENTITY)
                {
                    if (mEntityAddDeleteLoggingEnabled)
                    {
                        if (updatedEntity != null)
                        {
                            PCILOG.LogToSysLog(updatedEntity, "Added");
                        }
                    }
                }
                else if (PreviousFormState == FORM_MODES_ENUM.NEW_GROUP)
                {
                    if (mEntityAddDeleteLoggingEnabled)
                    {
                        if (updatedGroup != null)
                        {
                            PCILOG.LogToSysLog(updatedGroup, "Added");
                        }
                    }
                }
                ///An entity was deleted, so use the deleted verbiage in the log.
                else if (PreviousFormState == FORM_MODES_ENUM.DELETE_ENTITY)
                {
                    if (mEntityAddDeleteLoggingEnabled)
                    {
                        if (updatedEntity != null)
                        {
                            PCILOG.LogToSysLog(updatedEntity, "Deleted");
                        }
                    }
                }
                ///An entity was deleted, so use the deleted verbiage in the log.
                else if (PreviousFormState == FORM_MODES_ENUM.DELETE_GROUP)
                {
                    if (mEntityAddDeleteLoggingEnabled)
                    {
                        if (updatedGroup != null)
                        {
                            PCILOG.LogToSysLog(updatedGroup, "Deleted");
                        }
                    }
                }

                try
                {
                    Context.SaveChanges();
                }
                catch (Exception e)
                {
                    UMD.ShowGuiMessageSTASafe_NOTHROW("There was an error while trying to update the system with your changes.  This may be due to a conflict with your desired configuration and that which is being accessed in another terminal.  Please try to make your changes again.  If this problem persists, notify your technical support contact.");

                    ///Prevent a crash in case we get another exception.
                    try
                    {
                        List<EntityObject> entityList = GetEntityObjectSet();
                        List<EntityObject> groupList = GetGroupObjectSet();

                        if (entityList != null)
                        {
                            Context.Refresh(RefreshMode.StoreWins, entityList);
                        }

                        if (groupList != null)
                        {
                            Context.Refresh(RefreshMode.StoreWins, groupList);
                        }

                        Logging.LogException(e);
                    }
                    catch { }
                }
            }
            ///If the user canceled the changes or is calling to refresh, we need to assure the context
            ///has the latest data.
            else if (state == FORM_MODES_ENUM.LOCKED_CANCEL || state == FORM_MODES_ENUM.REFRESHED)
            {
                try
                {
                    List<EntityObject> entityList = GetEntityObjectSet();
                    List<EntityObject> groupList = GetGroupObjectSet();

                    if (entityList != null)
                    {
                        Context.Refresh(RefreshMode.StoreWins, entityList);
                    }

                    if (groupList != null)
                    {
                        Context.Refresh(RefreshMode.StoreWins, groupList);
                    }
                }
                catch (Exception e)
                {
                    Logging.LogException(e);
                }
            }

            ///*** Determine if we should show the GUI keyboard. ***
            if (state == FORM_MODES_ENUM.NEW_ENTITY || state == FORM_MODES_ENUM.EDIT_FORM ||
                state == FORM_MODES_ENUM.NEW_GROUP || state == FORM_MODES_ENUM.SAVE_THEN_EDIT)
            {
                ShowKeyboard();
            }
            else
            {
                if (HideKeyboard != null)
                {
                    HideKeyboard();
                }
            }

            ///****** CONTROLS - WITH LOGGING and Notify other DBASES except on Delete and New ***********
            ///Either enable or disable the forms controls based on the current state.
            if (null != uiElementsList)
            {
                foreach (UIElement uielem in uiElementsList)
                {
                    RecursiveChangeState(uielem, state);
                }
            }

            ///Some forms have extra buttons that may need to be hidden or made visible in certain states.
            foreach (UIElement elem in mListOfControlsToHideInNonEditMode)
            {
                if (state == FORM_MODES_ENUM.EDIT_FORM || state == FORM_MODES_ENUM.NEW_ENTITY || state == FORM_MODES_ENUM.NEW_GROUP || state == FORM_MODES_ENUM.SAVE_THEN_EDIT)
                {
                    elem.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    elem.Visibility = System.Windows.Visibility.Hidden;
                }
            }

            ///Some forms have extra buttons that may need to be enabled or disabled while editing or not.
            foreach (UIElement elem in mListOfControlsToDisableInNonEditMode)
            {
                if (state == FORM_MODES_ENUM.EDIT_FORM || state == FORM_MODES_ENUM.NEW_ENTITY || state == FORM_MODES_ENUM.NEW_GROUP || state == FORM_MODES_ENUM.SAVE_THEN_EDIT)
                {
                    if (mListOfControlsToDisableInAllModes.Contains(elem))
                    {
                        elem.IsEnabled = false;
                    }
                    else
                    {
                        elem.IsEnabled = true;
                    }
                }
                else
                {
                    elem.IsEnabled = false;
                }
            }

            if (state == FORM_MODES_ENUM.LOCKED || state == FORM_MODES_ENUM.LOCKED_CANCEL)
            {
                if (!mEditIsDisabled)
                {
                    EditFormButton.Visibility = Visibility.Visible;
                }
                else
                {
                    EditFormButton.Visibility = Visibility.Hidden;
                }

                CancelEditButton.Visibility = Visibility.Hidden;
                SaveFormChangesButton.Visibility = Visibility.Hidden;
                NewGroupButton.Visibility = Visibility.Hidden;
                DeleteGroupButton.Visibility = Visibility.Hidden;
                NewEntityButton.Visibility = Visibility.Hidden;
                DeleteEntityButton.Visibility = Visibility.Hidden;
            }
            else if (state == FORM_MODES_ENUM.NEW_ENTITY)
            {
                EditFormButton.Visibility = Visibility.Hidden;

                if (!mCancelIsDisabled)
                {
                    CancelEditButton.Visibility = Visibility.Visible;
                }
                else
                {
                    CancelEditButton.Visibility = Visibility.Hidden;
                }

                if (!mSaveIsDisabled)
                {
                    SaveFormChangesButton.Visibility = Visibility.Visible;
                }

                NewGroupButton.Visibility = Visibility.Hidden;
                DeleteGroupButton.Visibility = Visibility.Hidden;
                NewEntityButton.Visibility = Visibility.Hidden;
                DeleteEntityButton.Visibility = Visibility.Hidden;
            }
            else if (state == FORM_MODES_ENUM.EDIT_FORM)
            {
                EditFormButton.Visibility = Visibility.Hidden;

                if (!mCancelIsDisabled)
                {
                    CancelEditButton.Visibility = Visibility.Visible;
                }
                else
                {
                    CancelEditButton.Visibility = Visibility.Hidden;
                }

                if (!mSaveIsDisabled)
                {
                    SaveFormChangesButton.Visibility = Visibility.Visible;
                }
                else
                {
                    saveFormChangesButton.Visibility = Visibility.Hidden;
                }

                if (!mDeleteEntityIsDisabled)
                {
                    DeleteEntityButton.Visibility = Visibility.Visible;
                }
                else
                {
                    DeleteEntityButton.Visibility = Visibility.Hidden;
                }

                if (!mDeleteGroupIsDisabled)
                {
                    DeleteGroupButton.Visibility = Visibility.Visible;
                }
                else
                {
                    DeleteGroupButton.Visibility = Visibility.Hidden;
                }

                if (!mNewGroupIsDisabled)
                {
                    NewGroupButton.Visibility = Visibility.Visible;
                }
                else
                {
                    NewGroupButton.Visibility = Visibility.Hidden;
                }

                if (!mNewEntityIsDisabled)
                {
                    NewEntityButton.Visibility = Visibility.Visible;
                }
                else
                {
                    NewEntityButton.Visibility = Visibility.Hidden;
                }
            }
            else if (state == FORM_MODES_ENUM.DELETE_ENTITY || state == FORM_MODES_ENUM.DELETE_GROUP)
            {
                EditFormButton.Visibility = Visibility.Hidden;
                CancelEditButton.Visibility = Visibility.Hidden;
                SaveFormChangesButton.Visibility = Visibility.Visible;
                NewGroupButton.Visibility = Visibility.Hidden;
                DeleteGroupButton.Visibility = Visibility.Hidden;
                NewEntityButton.Visibility = Visibility.Hidden;
                DeleteEntityButton.Visibility = Visibility.Hidden;
            }
            else if (state == FORM_MODES_ENUM.NEW_GROUP)
            {
                EditFormButton.Visibility = Visibility.Hidden;

                if (!mCancelIsDisabled)
                {
                    CancelEditButton.Visibility = Visibility.Visible;
                }
                else
                {
                    CancelEditButton.Visibility = Visibility.Hidden;
                }

                if (!mSaveIsDisabled)
                {
                    SaveFormChangesButton.Visibility = Visibility.Visible;
                }

                NewGroupButton.Visibility = Visibility.Hidden;
                DeleteGroupButton.Visibility = Visibility.Hidden;
                NewEntityButton.Visibility = Visibility.Hidden;
                DeleteEntityButton.Visibility = Visibility.Hidden;
            }
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="uielem"></param>
        /// <param name="state"></param>
        private void RecursiveChangeState(UIElement uielem, FORM_MODES_ENUM state)
        {
            if (uielem is IDbLinkedControl)
            {
                IDbLinkedControl elem = uielem as IDbLinkedControl;

                if (state == FORM_MODES_ENUM.LOCKED || state == FORM_MODES_ENUM.LOCKED_CANCEL)
                {
                    elem.Lock(state);
                }
                else if (state == FORM_MODES_ENUM.EDIT_FORM || state == FORM_MODES_ENUM.NEW_ENTITY || state == FORM_MODES_ENUM.NEW_GROUP)
                {
                    if (!mListOfControlsToDisableInAllModes.Contains(uielem))
                    {
                        elem.Unlock(state);
                    }
                }
                else if (state == FORM_MODES_ENUM.SAVE_THEN_EDIT)
                {
                    elem.Lock(FORM_MODES_ENUM.LOCKED);
                    elem.Unlock(FORM_MODES_ENUM.EDIT_FORM);
                }
            }
            ///This is where the power of recursion kicks in.
            else if (uielem is Panel)
            {
                Panel p = uielem as Panel;
                foreach (UIElement panelUiElemen in p.Children)
                {
                    RecursiveChangeState(panelUiElemen, state);
                }
            }
            else if (uielem is GroupBox)
            {
                GroupBox gb = uielem as GroupBox;
                RecursiveChangeState(gb.Content as UIElement, state);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="uielem"></param>
        /// <param name="state"></param>
        protected bool RecursiveCheckMandatoryFields(UIElement uielem)
        {
            if (uielem is IDbLinkedControl)
            {
                IDbLinkedControl elem = uielem as IDbLinkedControl;
                return elem.Save();
            }
            ///This is where the power of recursion kicks in.
            else if (uielem is Panel)
            {
                Panel p = uielem as Panel;
                foreach (UIElement panelUiElemen in p.Children)
                {
                    if (!RecursiveCheckMandatoryFields(panelUiElemen))
                    {
                        return false;
                    }
                }
            }
            else if (uielem is GroupBox)
            {
                GroupBox gb = uielem as GroupBox;
                if (!RecursiveCheckMandatoryFields(gb.Content as UIElement))
                {
                    return false;
                }
            }
            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entityObj"></param>
        /// <param name="groupObject"></param>
        protected void SaveChanges(EntityObject entityObj, EntityObject groupObject)
        {
            try
            {
                if (SaveMe())
                {
                    UpdateControlsState(FORM_MODES_ENUM.SAVE_THEN_EDIT, entityObj, groupObject);
                }
                else
                {
                    this.CancelClicked();
                }

            }
            catch (Exception e)
            {
                Logging.LogException(e);
            }
        }

        /// <summary>
        /// Returns true if this form is in a mode that is editable.
        /// </summary>
        /// <returns></returns>
        public bool IsEditableMode()
        {
            if (currentFormState == FORM_MODES_ENUM.EDIT_FORM || 
                currentFormState == FORM_MODES_ENUM.NEW_ENTITY || 
                currentFormState == FORM_MODES_ENUM.DELETE_GROUP ||
                currentFormState == FORM_MODES_ENUM.NEW_GROUP ||
                currentFormState == FORM_MODES_ENUM.DELETE_ENTITY)
                return true;
            else
                return false;
        }

        /// <summary>
        /// Used to keep track of this forms state as the user transitions through the various stages during
        /// wizards, edits and etc.
        /// </summary>
        public enum FORM_MODES_ENUM
        {
            LOCKED = 0,
            SAVE_THEN_EDIT,
            NEW_ENTITY,
            EDIT_FORM,
            DELETE_ENTITY,
            NEW_GROUP,
            DELETE_GROUP,
            LOCKED_CANCEL,
            DBERROR,
            REFRESHED,
            UNITIALIZED
        }

        /// <summary>
        /// Holds the state of this form, i.e. are we in edit mode, new obj mode...
        /// </summary>
        private FORM_MODES_ENUM currentFormState = FORM_MODES_ENUM.UNITIALIZED;
        public FORM_MODES_ENUM CurrentFormState
        {
            get { return currentFormState; }
            set { currentFormState = value; }
        }

        /// <summary>
        /// Holds the state of this form, i.e. are we in edit mode, new obj mode...
        /// </summary>
        private FORM_MODES_ENUM previousFormState = FORM_MODES_ENUM.UNITIALIZED;
        public FORM_MODES_ENUM PreviousFormState
        {
            get { return previousFormState; }
            set { previousFormState = value; }
        }

        protected bool IsFetched = false;

        /// <summary>
        /// 
        /// </summary>
        public bool SaveClicked()
        {
            bool retVale = false;
            ///This must be done to assure that change notification occurs since we are updating the 
            ///text with a GUI keyboard.
            foreach (DbLinkedTextBox tb in mTextBoxesList)
            {
                tb.Focus();
            }

            if (VerifyFormEntries())
            {
                EntityObject entityObject = GetSelectedEntityObject();
                EntityObject groupObject = GetSelectedGroupObject();
                this.SaveChanges(entityObject, groupObject);

                ///We have to pull this number below to force binding to update and call the tostring methods.
                ComboBox comboBoxName = GetEntityComboBox();
                if (comboBoxName != null)
                {
                    ///The page that handles the ROLES is a special case because there are multiple
                    ///combo boxes that are bound.  The ROLE entity will come through this save
                    ///function and we don't want to try to bind the role to the user's name.  This
                    ///will prevent that.  
                    if (entityObject is ROLE)
                    {
                        ///Yes I am supposed to be blank.
                    }
                    else
                    {
                        comboBoxName.SelectedItem = null;
                        comboBoxName.SelectedItem = entityObject;
                    }
                }

                ComboBox comboBoxGroup = GetGroupComboBox();
                if (comboBoxGroup != null)
                {
                    comboBoxGroup.SelectedItem = null;
                    comboBoxGroup.SelectedItem = groupObject;
                }
                retVale = true;
                UpdateUsersEntitySource();
                UpdateUsersGroupSource();
                UpdateControlsState(FORM_MODES_ENUM.EDIT_FORM, null, null);
            }
            return retVale;
        }

        /// <summary>
        /// 
        /// </summary>
        public void CancelClicked()
        {
            if (IsFetched)
            {
                if (CurrentFormState == FORM_MODES_ENUM.NEW_ENTITY)
                {
                    ///If the count of the list is not zero, then set the selected item to the first element
                    ///in the list.
                    ComboBox comboBoxName = GetEntityComboBox();
                    if (comboBoxName != null)
                    {
                        object o = comboBoxName.SelectedItem;
                        if (o != null)
                        {
                            Context.DeleteObject(o);
                        }
                        Context.SaveChanges();
                        UpdateUsersEntitySource();

                        if (comboBoxName.Items.Count != 0)
                        {
                            comboBoxName.SelectedItem = comboBoxName.Items[0];
                        }
                        else
                        {
                            comboBoxName.SelectedItem = null;
                        }
                    }
                    this.CancelNewEntityWasClicked();
                }
                else if (CurrentFormState == FORM_MODES_ENUM.NEW_GROUP)
                {
                    ///If the count of the list is not zero, then set the selected item to the first element
                    ///in the list.
                    ComboBox comboBoxName = GetGroupComboBox();
                    if (comboBoxName != null)
                    {
                        object o = comboBoxName.SelectedItem;
                        if (o != null)
                        {
                            Context.DeleteObject(o);
                        }
                        Context.SaveChanges();
                        UpdateUsersGroupSource();

                        if (comboBoxName.Items.Count != 0)
                        {
                            comboBoxName.SelectedItem = comboBoxName.Items[0];
                        }
                        else
                        {
                            comboBoxName.SelectedItem = null;
                        }
                    }
                    this.CancelNewGroupWasClicked();
                }
                ///Lock the form
                UpdateControlsState(FORM_MODES_ENUM.LOCKED_CANCEL, null, null);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void EditFormClicked()
        {
            if (IsFetched)
            {
                this.EditStarted();
                UpdateControlsState(FORM_MODES_ENUM.EDIT_FORM, null, null);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        virtual public void NewEntityClicked()
        {
            try
            {
                if (IsFetched)
                {
                    EntityObject newObject = AddNewEntityObject();
                    Context.SaveChanges();
                    UpdateUsersEntitySource();
                    ComboBox comboBoxName = GetEntityComboBox();
                    if (comboBoxName != null)
                    {
                        comboBoxName.SelectedItem = newObject; ///Set the data context of the form fields to the newUser object.
                    }

                    UpdateControlsState(FORM_MODES_ENUM.NEW_ENTITY, newObject, null);
                }
            }
            catch (Exception e)
            {
                Logging.LogException(e);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        virtual public void NewGroupClicked()
        {
            try
            {
                if (IsFetched)
                {
                    EntityObject newObject = AddNewGroupObject();
                    Context.SaveChanges();
                    UpdateUsersGroupSource();
                    ComboBox comboBoxName = GetGroupComboBox();
                    if (comboBoxName != null)
                    {
                        comboBoxName.SelectedItem = newObject; ///Set the data context of the form fields to the newUser object.
                    }

                    UpdateControlsState(FORM_MODES_ENUM.NEW_GROUP, null, newObject);
                }
            }
            catch (Exception e)
            {
                Logging.LogException(e);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void DeleteEntityClicked()
        {
            try
            {
                if (IsFetched)
                {
                    object obj = GetSelectedEntityObject();
                    if (obj != null)
                    {
                        YesNoBox ynb = new YesNoBox("Are you sure you want to delete this configuration item?");
                        ynb.ShowDialog();
                        if (YesNoBox.LastResponse == UserResponse.YES)
                        {
                            try
                            {
                                UpdateControlsState(FORM_MODES_ENUM.DELETE_ENTITY, null, null);
                                MarkEntityDeleted();
                                UpdateControlsState(FORM_MODES_ENUM.LOCKED, GetSelectedEntityObject(), null);
                                UpdateUsersEntitySource();

                            }
                            catch (Exception e)
                            {
                                Logging.LogException(e);
                            }

                            ///If the count of the list is not zero, then set the selected item to the first element
                            ///in the list.
                            ComboBox comboBoxName = GetEntityComboBox();
                            if (comboBoxName != null)
                            {
                                if (comboBoxName.Items.Count != 0)
                                {
                                    comboBoxName.SelectedItem = comboBoxName.Items[0];
                                }
                                else
                                {
                                    comboBoxName.SelectedItem = null;
                                }
                            }
                        }
                    }
                    UpdateControlsState(FORM_MODES_ENUM.EDIT_FORM, GetSelectedEntityObject(), null);
                }
            }
            catch (Exception e)
            {
                Logging.LogException(e);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void DeleteGroupClicked()
        {
            try
            {
                if (IsFetched)
                {
                    object obj = GetSelectedGroupObject();
                    if (obj != null)
                    {
                        YesNoBox ynb = new YesNoBox("Are you sure you want to delete this configuration item?");
                        ynb.ShowDialog();
                        if (YesNoBox.LastResponse == UserResponse.YES)
                        {
                            try
                            {
                                UpdateControlsState(FORM_MODES_ENUM.DELETE_ENTITY, null, null);
                                MarkGroupDeleted();
                                UpdateControlsState(FORM_MODES_ENUM.LOCKED, null, GetSelectedGroupObject());
                                UpdateUsersGroupSource();
                            }
                            catch (Exception e)
                            {
                                Logging.LogException(e);
                            }

                            ///If the count of the list is not zero, then set the selected item to the first element
                            ///in the list.
                            ComboBox comboBoxName = GetGroupComboBox();
                            if (comboBoxName != null)
                            {
                                if (comboBoxName.Items.Count != 0)
                                {
                                    comboBoxName.SelectedItem = comboBoxName.Items[0];
                                }
                                else
                                {
                                    comboBoxName.SelectedItem = null;
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logging.LogException(e);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void RefreshClicked()
        {
            try
            {
                UpdateUsersEntitySource();
                UpdateUsersGroupSource();
                IsFetched = true;
            }
            catch (Exception ex)
            {
                Logging.LogException(ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="boolCancelCalled"></param>
        public void KeyBoardHiddenCallback_NOTHROW(UserResponse response)
        {
            try
            {
                if (response != UserResponse.ENTER)
                {
                    CancelClicked();
                }
            }
            catch (Exception exc)
            {
                Constants.ErrorDispatcher.Notify(Error.EType.E_PAGEINTERFACE_KEYBOARD_HIDDEN, exc);
            }
        }
    }
}
